home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume29 / zsh2.2 / part11 < prev    next >
Encoding:
Text File  |  1992-05-13  |  48.9 KB  |  2,589 lines

  1. Newsgroups: comp.sources.misc
  2. From: pfalstad@phoenix.Princeton.EDU (Paul Falstad)
  3. Subject:  v29i107:  zsh2.2 - The Z shell, Part11/17
  4. Message-ID: <1992May13.160546.10033@sparky.imd.sterling.com>
  5. X-Md4-Signature: 8ba6bb4f9f85c8e3f76c6193bb36799e
  6. Date: Wed, 13 May 1992 16:05:46 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: pfalstad@phoenix.Princeton.EDU (Paul Falstad)
  10. Posting-number: Volume 29, Issue 107
  11. Archive-name: zsh2.2/part11
  12. Environment: BSD
  13. Supersedes: zsh2.1: Volume 24, Issue 1-19
  14.  
  15. #!/bin/sh
  16. # this is aa.11 (part 11 of zsh2.2)
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file zsh2.2/src/params.c continued
  19. #
  20. if test ! -r _shar_seq_.tmp; then
  21.     echo 'Please unpack part 1 first!'
  22.     exit 1
  23. fi
  24. (read Scheck
  25.  if test "$Scheck" != 11; then
  26.     echo Please unpack part "$Scheck" next!
  27.     exit 1
  28.  else
  29.     exit 0
  30.  fi
  31. ) < _shar_seq_.tmp || exit 1
  32. if test ! -f _shar_wnt_.tmp; then
  33.     echo 'x - still skipping zsh2.2/src/params.c'
  34. else
  35. echo 'x - continuing file zsh2.2/src/params.c'
  36. sed 's/^X//' << 'SHAR_EOF' >> 'zsh2.2/src/params.c' &&
  37. X            (v->pm->sets.ifn)(v->pm,val);
  38. X            if (!v->pm->ct && lastbase != -1)
  39. X                v->pm->ct = lastbase;
  40. X            break;
  41. X        case PMFLAG_A:
  42. X            zerr("attempt to assign integer to array",NULL,0);
  43. X            break;
  44. X        }
  45. X}
  46. X
  47. Xvoid setintenv(s,val) /**/
  48. Xchar *s; long val;
  49. X{
  50. XParam pm;
  51. Xchar buf[20];
  52. X
  53. X    if ((pm = gethnode(s,paramtab)) && pm->env) {
  54. X        sprintf(buf,"%ld",val);
  55. X        pm->env = replenv(pm->env,buf);
  56. X    }
  57. X}
  58. X
  59. Xvoid setarrvalue(v,val) /**/
  60. XValue v;char **val;
  61. X{
  62. X    if (v->pm->flags & PMFLAG_r)
  63. X        return;
  64. X    if (pmtype(v->pm) != PMFLAG_A)
  65. X        {
  66. X        zerr("attempt to assign array value to non-array",NULL,0);
  67. X        return;
  68. X        }
  69. X    (v->pm->sets.afn)(v->pm,val);
  70. X}
  71. X
  72. Xchar *getsparamval(s,l) /**/
  73. Xchar *s;int l;
  74. X{
  75. Xchar sav,*t = s;
  76. XValue v;
  77. X
  78. X    if (sav = t[l])
  79. X        t[l] = '\0';
  80. X    if (!(v = getvalue(&s,0)))
  81. X        return NULL;
  82. X    t[l] = sav;
  83. X    t = getstrvalue(v);
  84. X    return t;
  85. X}
  86. X
  87. Xlong getiparam(s) /**/
  88. Xchar *s;
  89. X{
  90. XValue v;
  91. X
  92. X    if (!(v = getvalue(&s,0)))
  93. X        return 0;
  94. X    return getintvalue(v);
  95. X}
  96. X
  97. Xchar *getsparam(s) /**/
  98. Xchar *s;
  99. X{
  100. XValue v;
  101. X
  102. X    if (!(v = getvalue(&s,0)))
  103. X        return NULL;
  104. X    return getstrvalue(v);
  105. X}
  106. X
  107. Xchar **getaparam(s) /**/
  108. Xchar *s;
  109. X{
  110. XValue v;
  111. X
  112. X    if (!(v = getvalue(&s,0))) return NULL;
  113. X    return getarrvalue(v);
  114. X}
  115. X
  116. XParam setsparam(s,val) /**/
  117. Xchar *s;char *val;
  118. X{
  119. XValue v;
  120. Xchar *t = s;
  121. X
  122. X    if (!isident(s)) {
  123. X        zerr("not an identifier: %s",s,0);
  124. X        free(val);
  125. X        return NULL;
  126. X    }
  127. X    if (!(v = getvalue(&s,1)) || *s)
  128. X        return createparam(t,val,PMFLAG_s);
  129. X    if ((v->pm->flags & PMTYPE) != PMFLAG_s &&
  130. X            !(v->pm->flags & PMFLAG_SPECIAL)) {
  131. X        unsetparam(s);
  132. X        return createparam(t,val,PMFLAG_s);
  133. X    }
  134. X    setstrvalue(v,val);
  135. X    return v->pm;
  136. X}
  137. X
  138. XParam setaparam(s,val) /**/
  139. Xchar *s;char **val;
  140. X{
  141. XValue v;
  142. Xchar *t = s;
  143. X
  144. X    if (!isident(s))
  145. X        {
  146. X        zerr("not an identifier: %s",s,0);
  147. X        return NULL;
  148. X        }
  149. X    if (!(v = getvalue(&s,1)) || *s)
  150. X        return createparam(t,val,PMFLAG_A);
  151. X    if ((v->pm->flags & PMTYPE) != PMFLAG_A &&
  152. X            !(v->pm->flags & PMFLAG_SPECIAL)) {
  153. X        unsetparam(s);
  154. X        return createparam(t,val,PMFLAG_A);
  155. X    }
  156. X    setarrvalue(v,val);
  157. X    return v->pm;
  158. X}
  159. X
  160. XParam setiparam(s,val) /**/
  161. Xchar *s;long val;
  162. X{
  163. XValue v;
  164. Xchar *t = s;
  165. XParam pm;
  166. X
  167. X    if (!isident(s))
  168. X        {
  169. X        zerr("not an identifier: %s",s,0);
  170. X        return NULL;
  171. X        }
  172. X    if (!(v = getvalue(&s,0)))
  173. X        {
  174. X        pm = createparam(t,NULL,PMFLAG_i);
  175. X        pm->u.val = val;
  176. X        return pm;
  177. X        }
  178. X    setintvalue(v,val);
  179. X    return v->pm;
  180. X}
  181. X
  182. Xvoid unsetparam(s) /**/
  183. Xchar *s;
  184. X{
  185. XParam pm;
  186. X
  187. X    if (!(pm = gethnode(s,paramtab)))
  188. X        return;
  189. X    if (pm->flags & PMFLAG_r)
  190. X        return;
  191. X    unsetflag = 1;
  192. X    switch (pmtype(pm))
  193. X        {
  194. X        case 0:
  195. X            (pm->sets.cfn)(pm,ztrdup(""));
  196. X            break;
  197. X        case PMFLAG_i:
  198. X            (pm->sets.ifn)(pm,0);
  199. X            break;
  200. X        case PMFLAG_A:
  201. X            (pm->sets.afn)(pm,mkarray(NULL));
  202. X            break;
  203. X        }
  204. X    if (pmtype(pm) == PMFLAG_s && (pm->flags & PMFLAG_x)) {
  205. X        delenv(pm->env);
  206. X        free(pm->env);
  207. X    }
  208. X    if (!(pm->flags & PMFLAG_SPECIAL))
  209. X        freepm(remhnode(s,paramtab));
  210. X    unsetflag = 0;
  211. X}
  212. X
  213. Xvoid intsetfn(pm,x) /**/
  214. XParam pm;long x;
  215. X{
  216. X    pm->u.val = x;
  217. X}
  218. X
  219. Xlong intgetfn(pm) /**/
  220. XParam pm;
  221. X{
  222. X    return pm->u.val;
  223. X}
  224. X
  225. Xvoid strsetfn(pm,x) /**/
  226. XParam pm;char *x;
  227. X{
  228. X    if (x) 
  229. X        {
  230. X        if (pm->u.str)
  231. X            free(pm->u.str);
  232. X        pm->u.str = x;
  233. X        }
  234. X}
  235. X
  236. Xchar *strgetfn(pm) /**/
  237. XParam pm;
  238. X{
  239. X    return pm->u.str;
  240. X}
  241. X
  242. Xvoid nullsetfn(pm,x) /**/
  243. XParam pm; char *x;
  244. X{
  245. X    free(x);
  246. X}
  247. X
  248. Xvoid arrsetfn(pm,x) /**/
  249. XParam pm;char **x;
  250. X{
  251. Xint ct;
  252. X
  253. X    if (x)
  254. X        {
  255. X        if (pm->u.arr && pm->u.arr != x)
  256. X            freearray(pm->u.arr);
  257. X        pm->u.arr = x;
  258. X        for (ct = 0; *x; x++,ct++);
  259. X        pm->ct = ct;
  260. X        }
  261. X}
  262. X
  263. Xchar **arrgetfn(pm) /**/
  264. XParam pm;
  265. X{
  266. X    return pm->u.arr;
  267. X}
  268. X
  269. Xvoid intvarsetfn(pm,x) /**/
  270. XParam pm;long x;
  271. X{
  272. X    *((long *) pm->data) = x;
  273. X}
  274. X
  275. Xlong intvargetfn(pm) /**/
  276. XParam pm;
  277. X{
  278. X    return *((long *) pm->data);
  279. X}
  280. X
  281. Xvoid strvarsetfn(pm,x) /**/
  282. XParam pm;char *x;
  283. X{
  284. Xchar **q = ((char **) pm->data);
  285. X
  286. X    if (*q) free(*q);
  287. X    *q = x;
  288. X}
  289. X
  290. Xvoid strvarnonullsetfn(pm,x) /**/
  291. XParam pm;char *x;
  292. X{
  293. Xchar **q = ((char **) pm->data);
  294. X
  295. X    if (*q) free(*q);
  296. X    *q = (x) ? x : ztrdup("");
  297. X}
  298. X
  299. Xchar *strvargetfn(pm) /**/
  300. XParam pm;
  301. X{
  302. Xchar *s;
  303. X
  304. X    s = *((char **) pm->data);
  305. X    if (!s) return "";
  306. X    return s;
  307. X}
  308. X
  309. Xchar *strconstgetfn(pm) /**/
  310. XParam pm;
  311. X{
  312. X    return (char *) pm->data;
  313. X}
  314. X
  315. Xvoid colonarrsetfn(pm,x) /**/
  316. XParam pm;char *x;
  317. X{
  318. Xchar **s,**t,*u,*up;
  319. X
  320. X    s = colonsplit(x);
  321. X    free(x);
  322. X    if (pm->data != &fignore)
  323. X        for (t = s; *t; t++) {
  324. X            u = *t;
  325. X            if (*u == '~') *u = Tilde;
  326. X            if (*u == '=') *u = Equals;
  327. X            up = hcalloc(strlen(u)+1);
  328. X            strcpy(up,u);
  329. X            u = up;
  330. X            filesub(&u);
  331. X            if (!*u) u = ".";
  332. X            *t = ztrdup(u);
  333. X        }
  334. X    if (pm->data) {
  335. X        freearray(*((char ***) pm->data));
  336. X        *((char ***) pm->data) = s;
  337. X        if (pm->ename)
  338. X            arrfixenv(pm->ename,s);
  339. X    } else {
  340. X        freearray(path);
  341. X        path = s;
  342. X        newcmdnamtab();
  343. X        arrfixenv("PATH",s);
  344. X    }
  345. X}
  346. X
  347. Xchar *colonarrgetfn(pm) /**/
  348. XParam pm;
  349. X{
  350. X    if ((char **) pm->data)
  351. X        return colonjoin(*(char ***) pm->data);
  352. X    else
  353. X        return colonjoin(path);
  354. X}
  355. X
  356. Xchar **arrvargetfn(pm) /**/
  357. XParam pm;
  358. X{
  359. X    return *((char ***) pm->data);
  360. X}
  361. X
  362. Xvoid arrvarsetfn(pm,x) /**/
  363. XParam pm;char **x;
  364. X{
  365. X    if ((*(char ***) pm->data) != x)
  366. X        freearray(*(char ***) pm->data);
  367. X    *((char ***) pm->data) = x;
  368. X    if (pm->ename)
  369. X        arrfixenv(pm->ename,x);
  370. X}
  371. X
  372. Xchar **pathgetfn(pm) /**/
  373. XParam pm;
  374. X{
  375. X    return path;
  376. X}
  377. X
  378. Xvoid pathsetfn(pm,x) /**/
  379. XParam pm;char **x;
  380. X{
  381. X    if (path != x) freearray(path);
  382. X    path = x;
  383. X    newcmdnamtab();
  384. X    arrfixenv("PATH",x);
  385. X}
  386. X
  387. Xvoid hostcmdssetfn(pm,x) /**/
  388. XParam pm;char **x;
  389. X{
  390. X    compctl_process(x,CC_HOSTS|CC_FILES,NULL);
  391. X    freearray(x);
  392. X}
  393. X
  394. Xvoid optcmdssetfn(pm,x) /**/
  395. XParam pm;char **x;
  396. X{
  397. X    compctl_process(x,CC_OPTIONS,NULL);
  398. X    freearray(x);
  399. X}
  400. X
  401. Xvoid bindcmdssetfn(pm,x) /**/
  402. XParam pm;char **x;
  403. X{
  404. X    compctl_process(x,CC_BINDINGS,NULL);
  405. X    freearray(x);
  406. X}
  407. X
  408. Xvoid varcmdssetfn(pm,x) /**/
  409. XParam pm;char **x;
  410. X{
  411. X    compctl_process(x,CC_VARS,NULL);
  412. X    freearray(x);
  413. X}
  414. X
  415. Xchar **nullgetfn(pm) /**/
  416. XParam pm;
  417. X{
  418. Xstatic char *nl = NULL; return &nl;
  419. X}
  420. X
  421. Xvoid unsettablesetfn(pm,x) /**/
  422. XParam pm;char *x;
  423. X{ ; }
  424. X
  425. Xlong poundgetfn(pm) /**/
  426. XParam pm;
  427. X{
  428. X    return arrlen(pparams);
  429. X}
  430. X
  431. Xlong randomgetfn(pm) /**/
  432. XParam pm;
  433. X{
  434. X    return rand() & 0x7fff;
  435. X}
  436. X
  437. Xvoid randomsetfn(pm,v) /**/
  438. XParam pm;long v;
  439. X{
  440. X    srand((unsigned int) v);
  441. X}
  442. X
  443. Xlong secondsgetfn(pm) /**/
  444. XParam pm;
  445. X{
  446. X    return time(NULL)-shtimer;
  447. X}
  448. X
  449. Xvoid secondssetfn(pm,x) /**/
  450. XParam pm;long x;
  451. X{
  452. X    shtimer = time(NULL)-x;
  453. X}
  454. X
  455. Xlong uidgetfn(pm) /**/
  456. XParam pm;
  457. X{
  458. X    return getuid();
  459. X}
  460. X
  461. Xlong gidgetfn(pm) /**/
  462. XParam pm;
  463. X{
  464. X    return getegid();
  465. X}
  466. X
  467. Xchar *usernamegetfn(pm) /**/
  468. XParam pm;
  469. X{
  470. Xstruct passwd *pwd;
  471. X
  472. X    pwd = getpwuid(getuid());
  473. X    return pwd->pw_name;
  474. X}
  475. X
  476. Xchar *hostgetfn(pm) /**/
  477. XParam pm;
  478. X{
  479. Xstatic char hostnam[65];
  480. Xstatic int got = 0;
  481. X
  482. X    if (!got)
  483. X        {
  484. X        gethostname(hostnam,64);
  485. X        hostnam[64] = '\0';
  486. X        got = 1;
  487. X        }
  488. X    return hostnam;
  489. X}
  490. X
  491. Xchar *ifsgetfn(pm) /**/
  492. XParam pm;
  493. X{
  494. X    return ifs;
  495. X}
  496. X
  497. Xvoid ifssetfn(pm,x) /**/
  498. XParam pm;char *x;
  499. X{
  500. X    if (x) { free(ifs); ifs = x; }
  501. X    inittyptab();
  502. X}
  503. X
  504. Xvoid histsizesetfn(pm,v) /**/
  505. XParam pm;long v;
  506. X{
  507. X    if ((histsiz = v) <= 2) histsiz = 2;
  508. X    resizehistents();
  509. X}
  510. X
  511. Xlong histsizegetfn(pm) /**/
  512. XParam pm;
  513. X{
  514. X    return histsiz;
  515. X}
  516. X
  517. Xvoid lithistsizesetfn(pm,v) /**/
  518. XParam pm;long v;
  519. X{
  520. X    if ((lithistsiz = v) <= 2) lithistsiz = 2;
  521. X    resizehistents();
  522. X}
  523. X
  524. Xlong lithistsizegetfn(pm) /**/
  525. XParam pm;
  526. X{
  527. X    return lithistsiz;
  528. X}
  529. X
  530. Xvoid mailchecksetfn(pm,x) /**/
  531. XParam pm;long x;
  532. X{
  533. X    mailcheck = (unsetflag) ? 600 : x;
  534. X}
  535. X
  536. Xvoid pathasetfn(pm,x) /**/
  537. XParam pm;char **x;
  538. X{
  539. X    freearray(path);
  540. X    path = x;
  541. X    newcmdnamtab();
  542. X}
  543. X
  544. Xchar **pathagetfn(pm) /**/
  545. XParam pm;
  546. X{
  547. X    return path;
  548. X}
  549. X
  550. Xlong errnogetfn(pm) /**/
  551. XParam pm;
  552. X{
  553. X    return errno;
  554. X}
  555. X
  556. Xchar *dashgetfn(pm) /**/
  557. XParam pm;
  558. X{
  559. Xstatic char buf[100];
  560. Xchar *val = buf;
  561. Xint t0;
  562. X
  563. X    for (val = buf, t0 = ' ';t0 <= 'z'; t0++)
  564. X        if (opts[t0] == OPT_SET)
  565. X            *val++ = t0;
  566. X    *val = '\0';
  567. X    return buf;
  568. X}
  569. X
  570. Xvoid histcharssetfn(pm,x) /**/
  571. XParam pm;char *x;
  572. X{
  573. X    if (x) {
  574. X        bangchar = x[0];
  575. X        hatchar = (bangchar) ? x[1] : '\0';
  576. X        hashchar = (hatchar) ? x[2] : '\0';
  577. X        free(x);
  578. X    }
  579. X}
  580. X
  581. Xchar *histcharsgetfn(pm) /**/
  582. XParam pm;
  583. X{
  584. Xstatic char buf[4];
  585. X
  586. X    buf[0] = bangchar;
  587. X    buf[1] = hatchar;
  588. X    buf[2] = hashchar;
  589. X    buf[3] = '\0';
  590. X    return buf;
  591. X}
  592. X
  593. Xchar *homegetfn(pm) /**/
  594. XParam pm;
  595. X{
  596. X    return home;
  597. X}
  598. X
  599. Xvoid homesetfn(pm,x) /**/
  600. XParam pm;char *x;
  601. X{
  602. X    free(home);
  603. X    if (isset(CHASELINKS) && (home = xsymlink(x))) free(x);
  604. X    else home = x;
  605. X}
  606. X
  607. Xchar *wordcharsgetfn(pm) /**/
  608. XParam pm;
  609. X{
  610. X    return wordchars;
  611. X}
  612. X
  613. Xvoid wordcharssetfn(pm,x) /**/
  614. XParam pm;char *x;
  615. X{
  616. X    free(wordchars);
  617. X    if (x) wordchars = x;
  618. X    else wordchars = ztrdup(DEFWORDCHARS);
  619. X    inittyptab();
  620. X}
  621. X
  622. Xchar *underscoregetfn(pm) /**/
  623. XParam pm;
  624. X{
  625. Xchar *s,*t;
  626. X
  627. X    if (!(s = qgetevent(curhist-1)))
  628. X        return "";
  629. X    for (t = s+strlen(s); t > s; t--)
  630. X        if (*t == HISTSPACE)
  631. X            break;
  632. X    if (t != s)
  633. X        t++;
  634. X    return t;
  635. X}
  636. X
  637. Xchar *termgetfn(pm) /**/
  638. XParam pm;
  639. X{
  640. X    return term;
  641. X}
  642. X
  643. Xvoid termsetfn(pm,x) /**/
  644. XParam pm;char *x;
  645. X{
  646. X    if (term) free(term);
  647. X    term = x;
  648. X    if (!interact || unset(USEZLE))
  649. X        return;
  650. X    if (tgetent(termbuf,term) != 1)
  651. X        {
  652. X        zerr("can't find termcap info for %s",term,0);
  653. X        errflag = 0;
  654. X        termok = 0;
  655. X        }
  656. X    else
  657. X        {
  658. X        char tbuf[1024],*pp;
  659. X        int t0;
  660. X
  661. X        termok = 1;
  662. X        for (t0 = 0; t0 != TC_COUNT; t0++)
  663. X            {
  664. X            pp = tbuf;
  665. X            if (tcstr[t0])
  666. X                free(tcstr[t0]);
  667. X            if (!tgetstr(tccapnams[t0],&pp))
  668. X                tcstr[t0] = NULL, tclen[t0] = 0;
  669. X            else
  670. X                {
  671. X                tcstr[t0] = zalloc(tclen[t0] = pp-tbuf);
  672. X                memcpy(tcstr[t0],tbuf,tclen[t0]);
  673. X                }
  674. X            }
  675. X
  676. X/* if there's no termcap entry for cursor left, use \b. */
  677. X
  678. X        if (!tccan(TCLEFT))
  679. X            {
  680. X            tcstr[TCLEFT] = ztrdup("\b");
  681. X            tclen[TCLEFT] = 1;
  682. X            }
  683. X
  684. X/* if there's no termcap entry for clear, use ^L. */
  685. X
  686. X        if (!tccan(TCCLEARSCREEN))
  687. X            {
  688. X            tcstr[TCCLEARSCREEN] = ztrdup("\14");
  689. X            tclen[TCCLEARSCREEN] = 1;
  690. X            }
  691. X
  692. X/* if the termcap entry for down is \n, don't use it. */
  693. X
  694. X        if (tccan(TCDOWN) && tcstr[TCDOWN][0] == '\n')
  695. X            {
  696. X            tclen[TCDOWN] = 0;
  697. X            free(tcstr[TCDOWN]);
  698. X            tcstr[TCDOWN] = NULL;
  699. X            }
  700. X
  701. X/* if there's no termcap entry for cursor up, forget it.
  702. X    Use single line mode. */
  703. X
  704. X        if (!tccan(TCUP))
  705. X            termok = 0;
  706. X        }
  707. X}
  708. X
  709. Xvoid setparams() /**/
  710. X{
  711. Xchar **envp,**envp2,**envp3,*str;
  712. Xchar buf[50];
  713. Xstruct param *pm;
  714. Xint ct;
  715. X
  716. X    noerrs = 1;
  717. X    for (envp = environ, ct = 2; *envp; envp++,ct++);
  718. X    envp = environ;
  719. X    envp2 = envp3 = (char **) zalloc(sizeof(char *)*ct);
  720. X    for (; *envp; envp++)
  721. X        *envp2++ = ztrdup(*envp);
  722. X    *envp2 = NULL;
  723. X    envp = environ;
  724. X    environ = envp2 = envp3;
  725. X    for (; *envp; envp++,envp2++) {
  726. X        for (str = *envp; *str && *str != '='; str++);
  727. X        if (*str == '=') {
  728. X            char *iname;
  729. X
  730. X            *str = '\0';
  731. X            if (isident(*envp))
  732. X                pm = setsparam(iname = *envp,ztrdup(str+1));
  733. X            if (pm) {
  734. X                pm->flags |= PMFLAG_x;
  735. X                pm->env = *envp2;
  736. X                if (pm->flags & PMFLAG_SPECIAL)
  737. X                    pm->env = replenv(pm->env,getsparam(iname));
  738. X            }
  739. X            *str = '=';
  740. X        }
  741. X    }
  742. X    pm = gethnode("HOME",paramtab);
  743. X    if (!(pm->flags & PMFLAG_x)) {
  744. X        pm->flags |= PMFLAG_x;
  745. X        pm->env = addenv("HOME",home);
  746. X    }
  747. X    pm = gethnode("PWD",paramtab);
  748. X    if (!(pm->flags & PMFLAG_x)) {
  749. X        pm->flags |= PMFLAG_x;
  750. X        pm->env = addenv("PWD",pwd);
  751. X    }
  752. X    pm = gethnode("LOGNAME",paramtab);
  753. X    if (!(pm->flags & PMFLAG_x)) {
  754. X        pm->flags |= PMFLAG_x;
  755. X        pm->env = addenv("LOGNAME",logname);
  756. X    }
  757. X    pm = gethnode("SHLVL",paramtab);
  758. X    if (!(pm->flags & PMFLAG_x))
  759. X        pm->flags |= PMFLAG_x;
  760. X    sprintf(buf,"%d",++shlvl);
  761. X    pm->env = addenv("SHLVL",buf);
  762. X    noerrs = 0;
  763. X}
  764. X
  765. Xchar *mkenvstr(x,y) /**/
  766. Xchar *x;char *y;
  767. X{
  768. Xchar *z;
  769. Xint xl = strlen(x),yl = strlen(y);
  770. X
  771. X    z = zalloc(xl+yl+2);
  772. X    strcpy(z,x);
  773. X    z[xl] = '=';
  774. X    strcpy(z+xl+1,y);
  775. X    z[xl+yl+1] = '\0';
  776. X    return z;
  777. X}
  778. X
  779. Xvoid arrfixenv(s,t) /**/
  780. Xchar *s;char **t;
  781. X{
  782. Xchar **ep;
  783. Xint sl = strlen(s);
  784. X
  785. X    for (ep = environ; *ep; ep++)
  786. X        if (!strncmp(*ep,s,sl) && (*ep)[sl] == '=') {
  787. X            char *u = colonjoin(t);
  788. X            replenv(*ep,u);
  789. X            break;
  790. X        }
  791. X}
  792. X
  793. Xchar *replenv(e,value) /**/
  794. Xchar *e;char *value;
  795. X{
  796. Xchar **ep;
  797. X
  798. X    for (ep = environ; *ep; ep++)
  799. X        if (*ep == e)
  800. X            {
  801. X            char *s = e;
  802. X
  803. X            while (*s++ != '=');
  804. X            *s = '\0';
  805. X            *ep = zalloc(strlen(e)+strlen(value)+2);
  806. X            strcpy(*ep,e);
  807. X            strcat(*ep,value);
  808. X            free(e);
  809. X            return *ep;
  810. X            }
  811. X    return NULL;
  812. X}
  813. X
  814. Xchar *addenv(name,value) /**/
  815. Xchar *name;char *value;
  816. X{
  817. Xchar **ep,**ep2,**ep3;
  818. Xint envct;
  819. X
  820. X    for (ep = environ; *ep; ep++)
  821. X        {
  822. X        char *s = *ep,*t = name;
  823. X
  824. X        while (*s && *s == *t) s++,t++;
  825. X        if (*s == '=' && !*t)
  826. X            {
  827. X            free(*ep);
  828. X            return *ep = mkenvstr(name,value);
  829. X            }
  830. X        }
  831. X    envct = arrlen(environ);
  832. X    ep = ep2 = (char **) zalloc((sizeof (char *))*(envct+3));
  833. X    for (ep3 = environ; *ep2 = *ep3; ep3++,ep2++);
  834. X    *ep2 = mkenvstr(name,value);
  835. X    ep2[1] = NULL;
  836. X    free(environ);
  837. X    environ = ep;
  838. X    return *ep2;
  839. X}
  840. X
  841. Xvoid delenv(x) /**/
  842. Xchar *x;
  843. X{
  844. Xchar **ep;
  845. X
  846. X    ep = environ;
  847. X    for (; *ep; ep++)
  848. X        if (*ep == x)
  849. X            break;
  850. X    if (*ep)
  851. X        for (; ep[0] = ep[1]; ep++);
  852. X}
  853. X
  854. Xvoid convbase(s,v,base) /**/
  855. Xchar *s;long v;int base;
  856. X{
  857. Xint digs = 0;
  858. Xlong x;
  859. X
  860. X    if (base <= 1)
  861. X        base = 10;
  862. X    x = v;
  863. X    if (x < 0)
  864. X        {
  865. X        x = -x;
  866. X        digs++;
  867. X        }
  868. X    for (; x; digs++)
  869. X        x /= base;
  870. X    if (!digs)
  871. X        digs = 1;
  872. X    s[digs--] = '\0';
  873. X    x = (v < 0) ? -v : v;
  874. X    while (digs >= 0)
  875. X        {
  876. X        int dig = x%base;
  877. X        s[digs--] = (dig < 10) ? '0'+dig : dig-10+'A';
  878. X        x /= base;
  879. X        }
  880. X    if (v < 0)
  881. X        s[0] = '-';
  882. X}
  883. X
  884. X
  885. SHAR_EOF
  886. echo 'File zsh2.2/src/params.c is complete' &&
  887. chmod 0644 zsh2.2/src/params.c ||
  888. echo 'restore of zsh2.2/src/params.c failed'
  889. Wc_c="`wc -c < 'zsh2.2/src/params.c'`"
  890. test 24577 -eq "$Wc_c" ||
  891.     echo 'zsh2.2/src/params.c: original size 24577, current size' "$Wc_c"
  892. rm -f _shar_wnt_.tmp
  893. fi
  894. # ============= zsh2.2/src/subst.c ==============
  895. if test -f 'zsh2.2/src/subst.c' -a X"$1" != X"-c"; then
  896.     echo 'x - skipping zsh2.2/src/subst.c (File already exists)'
  897.     rm -f _shar_wnt_.tmp
  898. else
  899. > _shar_wnt_.tmp
  900. echo 'x - extracting zsh2.2/src/subst.c (Text)'
  901. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.2/src/subst.c' &&
  902. X/*
  903. X *
  904. X * subst.c - various substitutions
  905. X *
  906. X * This file is part of zsh, the Z shell.
  907. X *
  908. X * This software is Copyright 1992 by Paul Falstad
  909. X *
  910. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  911. X * use this software as long as: there is no monetary profit gained
  912. X * specifically from the use or reproduction of this software, it is not
  913. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  914. X * included prominently in any copy made. 
  915. X *
  916. X * The author make no claims as to the fitness or correctness of this software
  917. X * for any use whatsoever, and it is provided as is. Any use of this software
  918. X * is at the user's own risk. 
  919. X *
  920. X */
  921. X
  922. X#include "zsh.h"
  923. X#include <pwd.h>
  924. X
  925. X/* do substitutions before fork */
  926. X
  927. Xvoid prefork(list) /**/
  928. XLklist list;
  929. X{
  930. XLknode node = firstnode(list);
  931. Xint qt;
  932. X
  933. X    while (node)
  934. X        {
  935. X        char *str,*str3;
  936. X        
  937. X        str = str3 = getdata(node);
  938. X        if ((*str == Inang || *str == Outang || *str == Equals) &&
  939. X                str[1] == Inpar)
  940. X            {
  941. X            if (*str == Inang)
  942. X                setdata(node,getoutproc(str+2));        /* <(...) */
  943. X            else if (*str == Equals)
  944. X                setdata(node,getoutputfile(str+2));    /* =(...) */
  945. X            else
  946. X                setdata(node,getinproc(str+2));        /* >(...) */
  947. X            if (!getdata(node))
  948. X                {
  949. X                zerr("parse error in process substitution",NULL,0);
  950. X                return;
  951. X                }
  952. X            }
  953. X        else while (*str)
  954. X            {
  955. X            if ((qt = *str == Qstring) || *str == String)
  956. X                if (str[1] != Inpar)
  957. X                    if (str[1] == Inbrack)
  958. X                        {
  959. X                        arithsubst((vptr*) &str,&str3);    /* $[...] */
  960. X                        setdata(node,str3);
  961. X                        str = str3;
  962. X                        continue;
  963. X                        }
  964. X                    else
  965. X                        {
  966. X                        paramsubst(list,node,str,str3,qt);
  967. X                        if (errflag)
  968. X                            return;
  969. X                        str3 = str = getdata(node);
  970. X                        continue;
  971. X                        }
  972. X            str++;
  973. X            if (errflag)
  974. X                return;
  975. X            }
  976. X        if (*(char *) getdata(node))
  977. X            remnulargs(getdata(node));
  978. X        if (unset(IGNOREBRACES))
  979. X            while (hasbraces(getdata(node)))
  980. X                xpandbraces(list,&node);
  981. X        filesub((char **) getaddrdata(node));
  982. X        if (errflag)
  983. X            return;
  984. X        incnode(node);
  985. X        }
  986. X}
  987. X
  988. Xvoid postfork(list,doglob) /**/
  989. XLklist list;int doglob;
  990. X{
  991. XLknode node = firstnode(list);
  992. Xint glb = 1;
  993. X
  994. X    badcshglob = 0;
  995. X    if (isset(NOGLOBOPT) || !doglob)
  996. X        glb = 0;
  997. X    while (node)
  998. X        {
  999. X        char *str3,*str;
  1000. X        
  1001. X        str = str3 = getdata(node);
  1002. X        while (*str)
  1003. X            {
  1004. X            if (((*str == String || *str == Qstring) && str[1] == Inpar) ||
  1005. X                    *str == Tick || *str == Qtick)
  1006. X                {
  1007. X                Lknode n = prevnode(node);
  1008. X
  1009. X                commsubst(list,node,str,str3,
  1010. X                    (*str == Qstring || *str == Qtick));    /* `...`,$(...) */
  1011. X                if (errflag)
  1012. X                    return;
  1013. X                str = str3 = getdata(node = nextnode(n));
  1014. X                }
  1015. X            str++;
  1016. X            }
  1017. X        if (glb)
  1018. X            {
  1019. X            if (haswilds(getdata(node)))
  1020. X                glob(list,&node);
  1021. X            if (errflag)
  1022. X                return;
  1023. X            }
  1024. X        incnode(node);
  1025. X        }
  1026. X    if (badcshglob == 1) zerr("no match",NULL,0);
  1027. X}
  1028. X
  1029. X/* perform substitution on a single word */
  1030. X
  1031. Xvoid singsub(s) /**/
  1032. Xchar **s;
  1033. X{
  1034. XLklist foo;
  1035. Xchar *t;
  1036. X
  1037. X    for (t = *s; *t; t++)
  1038. X        if (*t == String)
  1039. X            *t = Qstring;
  1040. X        else if (*t == Tick)
  1041. X            *t = Qtick;
  1042. X    foo = newlist();
  1043. X    addnode(foo,*s);
  1044. X    prefork(foo);
  1045. X    if (errflag)
  1046. X        return;
  1047. X    postfork(foo,0);
  1048. X    if (errflag)
  1049. X        return;
  1050. X    *s = ugetnode(foo);
  1051. X    if (firstnode(foo))
  1052. X        zerr("ambiguous: %s",*s,0);
  1053. X}
  1054. X
  1055. X/* strdup, but returns "Nularg" if this is a null string */
  1056. X
  1057. Xvptr nstrdup(s) /**/
  1058. Xvptr s;
  1059. X{
  1060. Xchar *t = s;
  1061. Xchar u[2];
  1062. X
  1063. X    u[0] = Nularg; u[1] = '\0';
  1064. X    if (!*t)
  1065. X        return strdup(u);
  1066. X    return strdup(t);
  1067. X}
  1068. X
  1069. Xchar *dynread(stop) /**/
  1070. Xint stop;
  1071. X{
  1072. Xint bsiz = 256,ct = 0,c;
  1073. Xchar *buf = zalloc(bsiz),*ptr;
  1074. X    ptr = buf;
  1075. X    while ((c = hgetc()) != stop)
  1076. X        {
  1077. X        *ptr++ = c;
  1078. X        if (++ct == bsiz)
  1079. X            {
  1080. X            buf = realloc(buf,bsiz *= 2);
  1081. X            ptr = buf+ct;
  1082. X            }
  1083. X        }
  1084. X    *ptr = 0;
  1085. X    return buf;
  1086. X}
  1087. X
  1088. Xint filesub(namptr) /**/
  1089. Xchar **namptr;
  1090. X{
  1091. Xchar *str = *namptr,*cnam;
  1092. X
  1093. X    if (*str == Tilde && str[1] != '=')
  1094. X        {
  1095. X        if (str[1] == '+' && (str[2] == '/' || str[2] == '\0'))
  1096. X            {
  1097. X            char *foo = strdup(pwd);    /* ~+ */
  1098. X
  1099. X            str+=2;
  1100. X            modify(&foo,&str);
  1101. X            *namptr = dyncat(pwd,str);
  1102. X            return 1;
  1103. X            }
  1104. X        else if (str[1] == '-' && (str[2] == '/' || str[2] == '\0'))
  1105. X            {
  1106. X            char *foo;                /* ~- */
  1107. X
  1108. X            if (cnam = oldpwd)
  1109. X                foo = cnam;
  1110. X            else
  1111. X                foo = pwd;
  1112. X            str += 2;
  1113. X            foo = strdup(foo);
  1114. X            modify(&foo,&str);
  1115. X            *namptr = dyncat(foo,str);
  1116. X            return 1;
  1117. X            }
  1118. X        if (ialpha(str[1]))        /* ~foo */
  1119. X            {
  1120. X            char *ptr,*hom;
  1121. X            for (ptr = ++str; *ptr && iuser(*ptr); ptr++)
  1122. X                if (*ptr == '-')
  1123. X                    *ptr = '-';
  1124. X            if (*ptr && *ptr != '/') return 0;
  1125. X            if (!(hom = gethome(str,ptr-str)))
  1126. X                {
  1127. X                zerr("user not found: %l",str,ptr-str);
  1128. X                errflag = 1;
  1129. X                return 0;
  1130. X                }
  1131. X            modify(&hom,&ptr);
  1132. X            *namptr = dyncat(hom,ptr);
  1133. X            return 1;
  1134. X            }
  1135. X        else if (str[1] == '/')    /* ~/foo */
  1136. X            {
  1137. X            *namptr = dyncat(home,str+1);
  1138. X            return 1;
  1139. X            }
  1140. X        else if (!str[1])        /* ~ by itself */
  1141. X            {
  1142. X            *namptr = strdup(home);
  1143. X            return 1;
  1144. X            }
  1145. X        }
  1146. X    if (*str == Equals && iuser(str[1]) && unset(NOEQUALS))
  1147. X        {
  1148. X        char *ptr,*s,*ds;
  1149. X        int val;
  1150. X        
  1151. X        if (ialpha(str[1]))        /* =foo */
  1152. X            {
  1153. X            char sav,*pp;
  1154. X            for (pp = str+1; *pp && *pp != ':'; pp++);
  1155. X            sav = *pp;
  1156. X            *pp = '\0';
  1157. X            if (!(cnam = findcmd(str+1)))
  1158. X                {
  1159. X                zerr("%s not found",str+1,0);
  1160. X                errflag = 1;
  1161. X                return 0;
  1162. X                }
  1163. X            *namptr = cnam;
  1164. X            if ((*pp = sav) == ':')
  1165. X                {
  1166. X                modify(namptr,&pp);
  1167. X                s = *namptr;
  1168. X                *namptr = dyncat(*namptr,pp);
  1169. X                }
  1170. X            return 1;
  1171. X            }
  1172. X        if (str[1] == '-')     /* =- */
  1173. X            {
  1174. X            val = -1;
  1175. X            ptr = str+2;
  1176. X            }
  1177. X        else
  1178. X            val = zstrtol(str+1,&ptr,10);    /* =# */
  1179. X        ds = dstackent(val);
  1180. X        if (!ds)
  1181. X            return 1;
  1182. X        s = strdup(ds);
  1183. X        modify(&s,&ptr);
  1184. X        *namptr = dyncat(s,ptr);
  1185. X        return 1;
  1186. X        }
  1187. X    return 0;
  1188. X}
  1189. X
  1190. X/* get a named directory */
  1191. X
  1192. Xchar *gethome(user,len) /**/
  1193. Xchar *user;int len;
  1194. X{
  1195. Xchar sav,*str;
  1196. Xstruct passwd *pw;
  1197. X    if (len == 0)
  1198. X        return strdup(home);
  1199. X    sav = user[len];
  1200. X    user[len] = '\0';
  1201. X    if ((str = getsparamval(user,len)) && *str == '/')
  1202. X        {
  1203. X        str = strdup(str);
  1204. X        adduserdir(user,str);
  1205. X        user[len] = sav;
  1206. X        return str;
  1207. X        }
  1208. X    permalloc(); /* fixes iris bug--getpwnam calls strdup! */
  1209. X    pw = getpwnam(user);
  1210. X    lastalloc();
  1211. X    if (!pw) {
  1212. X        user[len] = sav;
  1213. X        return NULL;
  1214. X    }
  1215. X    str = xsymlink(pw->pw_dir);
  1216. X    adduserdir(user,str);
  1217. X    user[len] = sav;
  1218. X    return str;
  1219. X}
  1220. X
  1221. X/* `...`, $(...) */
  1222. X
  1223. Xvoid commsubst(l,n,str3,str,qt) /**/
  1224. XLklist l;Lknode n;char *str3;char *str;int qt;
  1225. X{
  1226. Xchar *str2;
  1227. XLknode where = prevnode(n);
  1228. XLklist pl;
  1229. X
  1230. X    if (*str3 == Tick || *str3 == Qtick)
  1231. X        {
  1232. X        *str3 = '\0';
  1233. X        for (str2 = ++str3; *str3 != Tick && *str3 != Qtick; str3++);
  1234. X        *str3++ = '\0';
  1235. X        }
  1236. X    else
  1237. X        {
  1238. X        *str3++ = '\0';
  1239. X        for (str2 = ++str3; *str3 != Outpar; str3++);
  1240. X        *str3++ = '\0';
  1241. X        }
  1242. X    uremnode(l,n);
  1243. X    if (!(pl = getoutput(str2,qt)))
  1244. X        {
  1245. X        zerr("parse error in command substitution",NULL,0);
  1246. X        errflag = 1;
  1247. X        return;
  1248. X        }
  1249. X    if (full(pl))
  1250. X        {
  1251. X        setdata(firstnode(pl),dyncat(str,peekfirst(pl)));
  1252. X        setdata(lastnode(pl),dyncat(getdata(lastnode(pl)),str3));
  1253. X        inslist(pl,where,l);
  1254. X        }
  1255. X    else
  1256. X        insnode(l,where,dyncat(str,str3));
  1257. X}
  1258. X
  1259. X/* parameter substitution */
  1260. X
  1261. Xvoid paramsubst(l,n,aptr,bptr,qt) /**/
  1262. XLklist l;Lknode n;char *aptr;char *bptr;int qt;
  1263. X{
  1264. Xchar *s = aptr,*u,*idbeg,*idend,*ostr = bptr;
  1265. Xint brs;            /* != 0 means ${...}, otherwise $... */
  1266. Xint colf;        /* != 0 means we found a colon after the name */
  1267. Xint doub = 0;    /* != 0 means we have %%, not %, or ##, not # */
  1268. Xint isarr = 0;
  1269. Xint wasnularr = 0;
  1270. Xint plan9 = isset(RCEXPANDPARAM);
  1271. Xint getlen = 0;
  1272. Xint vunset = 0;
  1273. Xint spbreak = isset(SHWORDSPLIT) && !qt;
  1274. Xchar *val = NULL,**aval = NULL;
  1275. Xint fwidth = 0;
  1276. XValue v;
  1277. X
  1278. X    *s++ = '\0';
  1279. X    if (!ialnum(*s) && *s != '#' && *s != Pound && *s != '-' &&
  1280. X            *s != '!' && *s != '$' && *s != String && *s != Qstring &&
  1281. X            *s != '?' && *s != Quest && *s != '_' &&
  1282. X            *s != '*' && *s != Star && *s != '@' && *s != '{' &&
  1283. X            *s != Inbrace && *s != '=' && *s != Hat && *s != '^') {
  1284. X        s[-1] = '$';
  1285. X        return;
  1286. X    }
  1287. X    if (brs = (*s == '{' || *s == Inbrace)) s++;
  1288. X    for (;;)
  1289. X        if (*s == '^' || *s == Hat)
  1290. X            plan9 ^= 1,s++;
  1291. X        else if (*s == '=')
  1292. X            spbreak ^= 1,s++;
  1293. X        else if ((*s == '#' || *s == Pound) && iident(s[1]))
  1294. X            getlen = 1,s++;
  1295. X        else
  1296. X            break;
  1297. X
  1298. X    idbeg = s;
  1299. X    if (!(v = getvalue(&s,1))) {
  1300. X        vunset = 1;
  1301. X        idend = s;
  1302. X    } else
  1303. X        if (isarr = v->isarr)
  1304. X            aval = getarrvalue(v);
  1305. X        else {
  1306. X            val = getstrvalue(v);
  1307. X            fwidth = v->pm->ct;
  1308. X            switch (v->pm->flags & (PMFLAG_L | PMFLAG_R | PMFLAG_Z)) {
  1309. X                char *t;
  1310. X                int t0;
  1311. X
  1312. X                case PMFLAG_L:
  1313. X                case PMFLAG_L|PMFLAG_Z:
  1314. X                    t = val;
  1315. X                    if (v->pm->flags & PMFLAG_Z)
  1316. X                        while (*t == '0') t++;
  1317. X                    else
  1318. X                        while (isep(*t)) t++;
  1319. X                    val = ncalloc(fwidth+1);
  1320. X                    val[fwidth] = '\0';
  1321. X                    if ((t0 = strlen(t)) > fwidth)
  1322. X                        t0 = fwidth;
  1323. X                    memset(val,' ',fwidth);
  1324. X                    strncpy(val,t,t0);
  1325. X                    break;
  1326. X                case PMFLAG_R:
  1327. X                case PMFLAG_Z:
  1328. X                case PMFLAG_Z|PMFLAG_R:
  1329. X                    if (strlen(val) < fwidth) {
  1330. X                        t = ncalloc(fwidth+1);
  1331. X                        memset(t,(v->pm->flags & PMFLAG_R) ? ' ' : '0',fwidth);
  1332. X                        if ((t0 = strlen(val)) > fwidth)
  1333. X                            t0 = fwidth;
  1334. X                        strcpy(t+(fwidth-t0),val);
  1335. X                        val = t;
  1336. X                    } else {
  1337. X                        t = ncalloc(fwidth+1);
  1338. X                        t[fwidth] = '\0';
  1339. X                        strncpy(t,val+strlen(val)-fwidth,fwidth);
  1340. X                        val = t;
  1341. X                    }
  1342. X                    break;
  1343. X                }
  1344. X            switch (v->pm->flags & (PMFLAG_l | PMFLAG_u)) {
  1345. X                char *t;
  1346. X
  1347. X                case PMFLAG_l:
  1348. X                    t = val;
  1349. X                    for (;*t;t++)
  1350. X                        *t = tulower(*t);
  1351. X                    break;
  1352. X                case PMFLAG_u:
  1353. X                    t = val;
  1354. X                    for (;*t;t++)
  1355. X                        *t = tuupper(*t);
  1356. X                    break;
  1357. X            }
  1358. X        }
  1359. X    if (colf = *s == ':') s++;
  1360. X    
  1361. X    /* check for ${..?...} or ${..=..} or one of those.  Only works
  1362. X        if the name is in braces. */
  1363. X
  1364. X    if (brs && (*s == '-' || *s == '=' || *s == '?' || *s == '+' || *s == '#' ||
  1365. X            *s == '%' || *s == Quest || *s == Pound)) {
  1366. X        if (v && v->isarr && (*s == '%' || *s == '#' || *s == Pound)) {
  1367. X            zerr("operator requires a scalar",NULL,0);
  1368. X            return;
  1369. X        }
  1370. X        if (*s == s[1]) {
  1371. X            s++;
  1372. X            doub = 1;
  1373. X        }
  1374. X        u = ++s;
  1375. X        if (brs) {
  1376. X            int bct = 1;
  1377. X
  1378. X            for (;;) {
  1379. X                if (*s == '{' || *s == Inbrace)
  1380. X                    bct++;
  1381. X                else if (*s == '}' || *s == Outbrace)
  1382. X                    bct--;
  1383. X                if (!bct || !*s)
  1384. X                    break;
  1385. X                s++;
  1386. X            }
  1387. X        } else {
  1388. X            while (*s++);
  1389. X            s--;
  1390. X        }
  1391. X        if (*s) *s++ = '\0';
  1392. X        if (colf && !vunset)
  1393. X            vunset = (isarr) ? !*aval : !*val;
  1394. X        switch ((int)(unsigned char)u[-1]) {
  1395. X            case '-':
  1396. X                if (vunset)
  1397. X                    val = strdup(u), isarr = 0;
  1398. X                break;
  1399. X            case '=':
  1400. X                if (vunset) {
  1401. X                    char sav = *idend;
  1402. X
  1403. X                    *idend = '\0';
  1404. X                    setsparam(idbeg,ztrdup(val = strdup(u)));
  1405. X                    *idend = sav;
  1406. X                    isarr = 0;
  1407. X                }
  1408. X                break;
  1409. X            case '?':
  1410. X            case (int)(unsigned char)Quest:
  1411. X                if (vunset) {
  1412. X                    zerr("%s",(*u) ? u : "parameter not set",0);
  1413. X                    if (!interact)
  1414. X                        exit(1);
  1415. X                    return;
  1416. X                }
  1417. X                break;
  1418. X            case '+':
  1419. X                if (vunset)
  1420. X                    val = strdup("");
  1421. X                else
  1422. X                    val = strdup(u);
  1423. X                isarr = 0;
  1424. X                break;
  1425. X            case '#':
  1426. X            case (int)(unsigned char)Pound:
  1427. X                if (vunset)
  1428. X                    val = strdup("");
  1429. X                singsub(&u);
  1430. X                getmatch(&val,u,doub);
  1431. X                break;
  1432. X            case '%':
  1433. X                if (vunset)
  1434. X                    val = strdup("");
  1435. X                singsub(&u);
  1436. X                getmatch(&val,u,doub+2);
  1437. X                break;
  1438. X        }
  1439. X    } else {        /* no ${...=...} or anything, but possible modifiers. */
  1440. X        if (vunset) {
  1441. X            if (isset(NOUNSET)) {
  1442. X                zerr("parameter not set",NULL,0);
  1443. X                return;
  1444. X            }
  1445. X            val = strdup("");
  1446. X        }
  1447. X        if (colf) {
  1448. X            s--;
  1449. X            if (!isarr) modify(&val,&s);
  1450. X            else {
  1451. X                char *ss = s;
  1452. X                char **ap = aval;
  1453. X                while (*ap) {
  1454. X                    ss = s;
  1455. X                    modify(ap,&ss);
  1456. X                }
  1457. X            }
  1458. X        }
  1459. X        if (brs) {
  1460. X            if (*s != '}' && *s != Outbrace) {
  1461. X                zerr("closing brace expected",NULL,0);
  1462. X                errflag = 1;
  1463. X                return;
  1464. X            }
  1465. X            s++;
  1466. X        }
  1467. X    }
  1468. X    if (errflag)
  1469. X        return;
  1470. X    if (getlen) {
  1471. X        long len = 0;
  1472. X        char buf[14];
  1473. X
  1474. X        if (isarr) {
  1475. X            char **ctr;
  1476. X            for (ctr = aval; *ctr; ctr++,len++);
  1477. X        } else
  1478. X            len = strlen(val);
  1479. X        sprintf(buf,"%ld",len);
  1480. X        val = strdup(buf);
  1481. X        isarr = 0;
  1482. X    }
  1483. X    if (isarr)
  1484. X        if (!aval || !aval[0]) {
  1485. X            if (isarr < 0)
  1486. X                wasnularr = 1;
  1487. X            val = strdup("");
  1488. X            isarr = 0;
  1489. X        } else if (!aval[1]) {
  1490. X            val = aval[0];
  1491. X            isarr = 0;
  1492. X        }
  1493. X    if (qt) {
  1494. X        if (isarr > 0) {
  1495. X            val = spacejoin(aval);
  1496. X            isarr = 0;
  1497. X        }
  1498. X    } else if (spbreak) {
  1499. X        if (isarr)
  1500. X            val = spacejoin(aval);
  1501. X        isarr = 1;
  1502. X        aval = spacesplit(val);
  1503. X        if (!aval || !aval[0]) {
  1504. X            val = strdup("");
  1505. X            isarr = 0;
  1506. X        } else if (!aval[1]) {
  1507. X            val = aval[0];
  1508. X            isarr = 0;
  1509. X        }
  1510. X        /* if only one member, not really an array */
  1511. X        if (!aval[1])
  1512. X            isarr = 0;
  1513. X    }
  1514. X    if (isarr)
  1515. X        if (plan9) {
  1516. X            int dlen;
  1517. X            char *y;
  1518. X
  1519. X            y = ncalloc((dlen = (char *) aptr-bptr+strlen(s)+1)+strlen(aval[0]));
  1520. X            setdata(n,y);
  1521. X            strcpy(y,ostr);
  1522. X            strcat(y,aval[0]);
  1523. X            strcat(y,s);
  1524. X            while (*++aval) {
  1525. X                char *x = ncalloc(dlen+strlen(*aval));
  1526. X
  1527. X                strcpy(x,ostr);
  1528. X                strcat(x,*aval);
  1529. X                strcat(x,s);
  1530. X                insnode(l,n,x), incnode(n);
  1531. X            }
  1532. X        } else {
  1533. X            char *zz;
  1534. X
  1535. X            zz = ncalloc((char *) aptr-(bptr)+strlen(aval[0])+1);
  1536. X            setdata(n,zz);
  1537. X            strcpy(zz,ostr);
  1538. X            strcat(zz,*aval++);
  1539. X            while (aval[1])
  1540. X                insnode(l,n,*aval++), incnode(n);
  1541. X            zz = ncalloc(strlen(*aval)+strlen(s)+1);
  1542. X            strcpy(zz,*aval);
  1543. X            strcat(zz,s);
  1544. X            insnode(l,n,zz);
  1545. X        }
  1546. X    else {
  1547. X        bptr = ncalloc((char *) aptr-bptr+strlen(val)+strlen(s)+1);
  1548. X        setdata(n,bptr);
  1549. X        strcpy(bptr,ostr);
  1550. X        strcat(bptr,val);
  1551. X        strcat(bptr,s);
  1552. X    }
  1553. X}
  1554. X
  1555. X/* arithmetic substitution */
  1556. X
  1557. Xvoid arithsubst(aptr,bptr) /**/
  1558. Xvptr *aptr;char **bptr;
  1559. X{
  1560. Xchar *s = *aptr,*t,buf[16];
  1561. Xlong v;
  1562. X
  1563. X    *s = '\0';
  1564. X    for (; *s != Outbrack; s++);
  1565. X    *s++ = '\0';
  1566. X    v = matheval((char *) *aptr+2);
  1567. X    sprintf(buf,"%ld",v);
  1568. X    t = ncalloc(strlen(*bptr)+strlen(buf)+strlen(s)+1);
  1569. X    strcpy(t,*bptr);
  1570. X    strcat(t,buf);
  1571. X    strcat(t,s);
  1572. X    *bptr = t;
  1573. X}
  1574. X
  1575. Xvoid modify(str,ptr) /**/
  1576. Xchar **str;char **ptr;
  1577. X{
  1578. Xchar *ptr1,*ptr2,*ptr3,del,*lptr;
  1579. Xint gbal;
  1580. X
  1581. X    if (**ptr == ':')
  1582. X        *str = strdup(*str);
  1583. X    while (**ptr == ':')
  1584. X        {
  1585. X        lptr = *ptr;
  1586. X        (*ptr)++;
  1587. X        gbal = 0;
  1588. Xhere:
  1589. X        switch(*(*ptr)++)
  1590. X            {
  1591. X            case 'h': remtpath(str); break;
  1592. X            case 'r': remtext(str); break;
  1593. X            case 'e': rembutext(str); break;
  1594. X            case 't': remlpaths(str); break;
  1595. X            case 'l': downcase(str); break;
  1596. X            case 'u': upcase(str); break;
  1597. X            case 's':
  1598. X                if (hsubl)
  1599. X                    free(hsubl);
  1600. X                if (hsubr)
  1601. X                    free(hsubr);
  1602. X                ptr1 = *ptr;
  1603. X                del = *ptr1++;
  1604. X                for (ptr2 = ptr1; *ptr2 != del && *ptr2; ptr2++);
  1605. X                if (!*ptr2)
  1606. X                    {
  1607. X                    zerr("bad subtitution",NULL,0);
  1608. X                    errflag = 1;
  1609. X                    return;
  1610. X                    }
  1611. X                *ptr2++ = '\0';
  1612. X                for (ptr3 = ptr2; *ptr3 != del && *ptr3; ptr3++);
  1613. X                if (*ptr3)
  1614. X                    *ptr3++ = '\0';
  1615. X                hsubl = ztrdup(ptr1);
  1616. X                hsubr = ztrdup(ptr2);
  1617. X                *ptr = ptr3;
  1618. X            case '&':
  1619. X                if (hsubl && hsubr)
  1620. X                    subst(str,hsubl,hsubr,gbal);
  1621. X                break;
  1622. X            case 'g': gbal = 1; goto here;
  1623. X            default: *ptr = lptr; return;
  1624. X            }
  1625. X        }
  1626. X}
  1627. X
  1628. X/* get a directory stack entry */
  1629. X
  1630. Xchar *dstackent(val) /**/
  1631. Xint val;
  1632. X{
  1633. XLknode node;
  1634. X    if ((val < 0 && !firstnode(dirstack)) || !val--)
  1635. X        return pwd;
  1636. X    if (val < 0)
  1637. X        node = lastnode(dirstack);
  1638. X    else
  1639. X        for (node = firstnode(dirstack); node && val; val--,incnode(node));
  1640. X    if (!node)
  1641. X        {
  1642. X        zerr("not enough dir stack entries.",NULL,0);
  1643. X        errflag = 1;
  1644. X        return NULL;
  1645. X        }
  1646. X    return getdata(node);
  1647. X}
  1648. X
  1649. X/* make an alias hash table node */
  1650. X
  1651. Xstruct alias *mkanode(txt,cmflag) /**/
  1652. Xchar *txt;int cmflag;
  1653. X{
  1654. Xstruct alias *ptr = (Alias) zcalloc(sizeof *ptr);
  1655. X
  1656. X    ptr->text  = txt;
  1657. X    ptr->cmd = cmflag;
  1658. X    ptr->inuse = 0;
  1659. X    return ptr;
  1660. X}
  1661. SHAR_EOF
  1662. chmod 0644 zsh2.2/src/subst.c ||
  1663. echo 'restore of zsh2.2/src/subst.c failed'
  1664. Wc_c="`wc -c < 'zsh2.2/src/subst.c'`"
  1665. test 14912 -eq "$Wc_c" ||
  1666.     echo 'zsh2.2/src/subst.c: original size 14912, current size' "$Wc_c"
  1667. rm -f _shar_wnt_.tmp
  1668. fi
  1669. # ============= zsh2.2/src/table.c ==============
  1670. if test -f 'zsh2.2/src/table.c' -a X"$1" != X"-c"; then
  1671.     echo 'x - skipping zsh2.2/src/table.c (File already exists)'
  1672.     rm -f _shar_wnt_.tmp
  1673. else
  1674. > _shar_wnt_.tmp
  1675. echo 'x - extracting zsh2.2/src/table.c (Text)'
  1676. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.2/src/table.c' &&
  1677. X/*
  1678. X *
  1679. X * table.c - linked lists and hash tables
  1680. X *
  1681. X * This file is part of zsh, the Z shell.
  1682. X *
  1683. X * This software is Copyright 1992 by Paul Falstad
  1684. X *
  1685. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  1686. X * use this software as long as: there is no monetary profit gained
  1687. X * specifically from the use or reproduction of this software, it is not
  1688. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  1689. X * included prominently in any copy made. 
  1690. X *
  1691. X * The author make no claims as to the fitness or correctness of this software
  1692. X * for any use whatsoever, and it is provided as is. Any use of this software
  1693. X * is at the user's own risk. 
  1694. X *
  1695. X */
  1696. X
  1697. X#define TABLE_C
  1698. X#include "zsh.h"
  1699. X
  1700. X/* get an empty linked list header */
  1701. X
  1702. XLklist newlist() /**/
  1703. X{
  1704. XLklist list;
  1705. X    list = (Lklist) alloc(sizeof *list);
  1706. X    list->first = 0;
  1707. X    list->last = (Lknode) list;
  1708. X    return list;
  1709. X}
  1710. X
  1711. X/* get an empty hash table */
  1712. X
  1713. XHashtab newhtable(size) /**/
  1714. Xint size;
  1715. X{
  1716. XHashtab ret;
  1717. X    ret = (Hashtab) zcalloc(sizeof *ret);
  1718. X    ret->hsize = size;
  1719. X    ret->nodes = (Hashnode*) zcalloc(size*sizeof(Hashnode));
  1720. X    return ret;
  1721. X}
  1722. X/* Peter Weinberger's hash function */
  1723. X
  1724. Xint hasher(s) /**/
  1725. Xchar *s;
  1726. X{
  1727. Xunsigned hash = 0,g;
  1728. X    for (; *s; s++) {
  1729. X        hash = (hash << 4) + *s;
  1730. X        if (g = hash & 0xf0000000) {
  1731. X            hash ^= g;
  1732. X            hash ^= g >> 24;
  1733. X        }
  1734. X    }
  1735. X    return hash;
  1736. X}
  1737. X
  1738. X/* add a node to a hash table */
  1739. X
  1740. Xvoid Addhnode(nam,dat,ht,freefunc,canfree) /**/
  1741. Xchar *nam;vptr dat;Hashtab ht;FFunc freefunc;int canfree;
  1742. X{
  1743. Xint hval = hasher(nam) % ht->hsize;
  1744. Xstruct hashnode **hp = ht->nodes+hval,*hn;
  1745. X    for (; *hp; hp = &(*hp)->next)
  1746. X        if (!strcmp((*hp)->nam,nam)) {
  1747. X            if ((*hp)->canfree) free((*hp)->nam);
  1748. X            hn = dat;
  1749. X            hn->next = (*hp)->next;
  1750. X            if (!freefunc) zerr("attempt to call NULL freefunc",NULL,0);
  1751. X            else freefunc(*hp);
  1752. X            *hp = hn;
  1753. X            hn->nam = nam;
  1754. X            hn->canfree = canfree;
  1755. X            return;
  1756. X        }
  1757. X    hn = (Hashnode) dat;
  1758. X    hn->nam = nam;
  1759. X    hn->canfree = canfree;
  1760. X    hn->next = ht->nodes[hval];
  1761. X    ht->nodes[hval] = hn;
  1762. X    if (++ht->ct == ht->hsize*4) expandhtab(ht);
  1763. X}
  1764. X
  1765. X/* add a node to command hash table */
  1766. X
  1767. Xvoid addhcmdnode(nam,pnam) /**/
  1768. Xchar *nam;char **pnam;
  1769. X{
  1770. Xint hval = hasher(nam) % cmdnamtab->hsize;
  1771. Xstruct hashnode *hp = cmdnamtab->nodes[hval],*hn;
  1772. XCmdnam cc;
  1773. X    for (; hp; hp = hp->next) if (!strcmp(hp->nam,nam)) return;
  1774. X    cc = (Cmdnam) zcalloc(sizeof *cc);
  1775. X    cc->type = EXCMD;
  1776. X    cc->u.nam = tricat(*pnam,"/",nam);
  1777. X    cc->pcomp = pnam;
  1778. X    hn = (Hashnode) cc;
  1779. X    hn->nam = ztrdup(nam);
  1780. X    hn->canfree = 1;
  1781. X    hn->next = cmdnamtab->nodes[hval];
  1782. X    cmdnamtab->nodes[hval] = hn;
  1783. X    if (++cmdnamtab->ct == cmdnamtab->hsize*4) expandhtab(cmdnamtab);
  1784. X}
  1785. X
  1786. X/* expand hash tables when they get too many entries */
  1787. X
  1788. Xvoid expandhtab(ht) /**/
  1789. XHashtab ht;
  1790. X{
  1791. Xstruct hashnode **arr,**ha,*hn,*hp;
  1792. Xint osize = ht->hsize,nsize = osize*8;
  1793. X
  1794. X    ht->hsize = nsize;
  1795. X    arr = ht->nodes;
  1796. X    ht->nodes = (Hashnode*) zcalloc(nsize*sizeof(struct hashnode *));
  1797. X    for (ha = arr; osize; osize--,ha++)
  1798. X        for (hn = *ha; hn; ) {
  1799. X            hp = hn->next;
  1800. X            Addhnode(hn->nam,(vptr)hn,ht,NULL,hn->canfree);
  1801. X            hn = hp;
  1802. X        }
  1803. X    free(arr);
  1804. X}
  1805. X
  1806. X/* get an entry in a hash table */
  1807. X
  1808. Xvptr gethnode(nam,ht) /**/
  1809. Xchar *nam;Hashtab ht;
  1810. X{
  1811. Xint hval = hasher(nam) % ht->hsize;
  1812. Xstruct hashnode *hn = ht->nodes[hval];
  1813. X    for (; hn; hn = hn->next) if (!strcmp(hn->nam,nam)) return (vptr)hn;
  1814. X    return NULL;
  1815. X}
  1816. Xvoid freehtab(ht,freefunc) /**/
  1817. XHashtab ht;FFunc freefunc;
  1818. X{
  1819. Xint val;
  1820. Xstruct hashnode *hn,**hp = &ht->nodes[0],*next;
  1821. X    for (val = ht->hsize; val; val--,hp++)
  1822. X        for (hn = *hp; hn; ) {
  1823. X            next = hn->next;
  1824. X            if (hn->canfree) free(hn->nam);
  1825. X            freefunc(hn);
  1826. X            hn = next;
  1827. X        }
  1828. X    free(ht->nodes);
  1829. X    free(ht);
  1830. X}
  1831. X
  1832. X/* remove a hash table entry and return a pointer to it */
  1833. X
  1834. Xvptr remhnode(nam,ht) /**/
  1835. Xchar *nam;Hashtab ht;
  1836. X{
  1837. Xint hval = hasher(nam) % ht->hsize;
  1838. Xstruct hashnode *hn = ht->nodes[hval],*hp;
  1839. X
  1840. X    if (!hn) return NULL;
  1841. X    if (!strcmp(hn->nam,nam)) {
  1842. X        ht->nodes[hval] = hn->next;
  1843. X        if (hn->canfree) free(hn->nam);
  1844. X        ht->ct--;
  1845. X        return (vptr)hn;
  1846. X    }
  1847. X    for (hp = hn, hn = hn->next; hn; hn = (hp = hn)->next)
  1848. X        if (!strcmp(hn->nam,nam)) {
  1849. X            hp->next = hn->next;
  1850. X            if (hn->canfree) free(hn->nam);
  1851. X            ht->ct--;
  1852. X            return (vptr)hn;
  1853. X        }
  1854. X    return NULL;
  1855. X}
  1856. X
  1857. X/* insert a node in a linked list after 'llast' */
  1858. X
  1859. Xvoid insnode(list,llast,dat) /**/
  1860. XLklist list;Lknode llast;vptr dat;
  1861. X{
  1862. XLknode tmp;
  1863. X    tmp = llast->next;
  1864. X    llast->next = (Lknode) alloc(sizeof *tmp);
  1865. X    llast->next->last = llast;
  1866. X    llast->next->dat = dat;
  1867. X    llast->next->next = tmp;
  1868. X    if (tmp) tmp->last = llast->next;
  1869. X    else list->last = llast->next;
  1870. X}
  1871. X
  1872. Xvoid addnodeinorder(x,dat) /**/
  1873. XLklist x; char *dat;
  1874. X{
  1875. XLknode y, l = NULL;
  1876. Xint val = 123;
  1877. X
  1878. X    for (y = firstnode(x); y; incnode(y)) {
  1879. X        if ((val = forstrcmp((char **) &y->dat, &dat)) >= 0) break;
  1880. X        l = y;
  1881. X    }
  1882. X    if (!val) return;
  1883. X    if (l == NULL) insnode(x, (Lknode) x, dat);
  1884. X    else insnode(x, l, dat);
  1885. X}
  1886. X
  1887. X
  1888. X/* remove a node from a linked list */
  1889. X
  1890. Xvptr remnode(list,nd) /**/
  1891. XLklist list;Lknode nd;
  1892. X{
  1893. Xvptr dat;
  1894. X
  1895. X    nd->last->next = nd->next;
  1896. X    if (nd->next) nd->next->last = nd->last;
  1897. X    else list->last = nd->last;
  1898. X    dat = nd->dat;
  1899. X    free(nd);
  1900. X    return dat;
  1901. X}
  1902. X
  1903. X/* remove a node from a linked list */
  1904. X
  1905. Xvptr uremnode(list,nd) /**/
  1906. XLklist list;Lknode nd;
  1907. X{
  1908. Xvptr dat;
  1909. X
  1910. X    nd->last->next = nd->next;
  1911. X    if (nd->next) nd->next->last = nd->last;
  1912. X    else list->last = nd->last;
  1913. X    dat = nd->dat;
  1914. X    return dat;
  1915. X}
  1916. X
  1917. X/* delete a character in a string */
  1918. X
  1919. Xvoid chuck(str) /**/
  1920. Xchar *str;
  1921. X{
  1922. X    while (str[0] = str[1]) str++;
  1923. X}
  1924. X
  1925. X/* get top node in a linked list */
  1926. X
  1927. Xvptr getnode(list) /**/
  1928. XLklist list;
  1929. X{
  1930. Xvptr dat;
  1931. XLknode node = list->first;
  1932. X    if (!node)
  1933. X        return NULL;
  1934. X    dat = node->dat;
  1935. X    list->first = node->next;
  1936. X    if (node->next)
  1937. X        node->next->last = (Lknode) list;
  1938. X    else
  1939. X        list->last = (Lknode) list;
  1940. X    free(node);
  1941. X    return dat;
  1942. X}
  1943. X
  1944. X/* get top node in a linked list without freeing */
  1945. X
  1946. Xvptr ugetnode(list) /**/
  1947. XLklist list;
  1948. X{
  1949. Xvptr dat;
  1950. XLknode node = list->first;
  1951. X    if (!node)
  1952. X        return NULL;
  1953. X    dat = node->dat;
  1954. X    list->first = node->next;
  1955. X    if (node->next)
  1956. X        node->next->last = (Lknode) list;
  1957. X    else
  1958. X        list->last = (Lknode) list;
  1959. X    return dat;
  1960. X}
  1961. X
  1962. Xvoid freetable(tab,freefunc) /**/
  1963. XLklist tab;FFunc freefunc;
  1964. X{
  1965. XLknode node = tab->first,next;
  1966. X    while (node) {
  1967. X        next = node->next;
  1968. X        if (freefunc) freefunc(node->dat);
  1969. X        free(node);
  1970. X        node = next;
  1971. X    }
  1972. X    free(tab);
  1973. X}
  1974. Xchar *ztrstr(s,t) /**/
  1975. Xchar *s;char *t;
  1976. X{
  1977. Xchar *p1,*p2;
  1978. X    for (; *s; s++) {
  1979. X        for (p1 = s, p2 = t; *p2; p1++,p2++)
  1980. X            if (*p1 != *p2) break;
  1981. X        if (!*p2) return (char *) s;
  1982. X    }
  1983. X    return NULL;
  1984. X}
  1985. X
  1986. X/* insert a list in another list */
  1987. X
  1988. Xvoid inslist(l,where,x) /**/
  1989. XLklist l;Lknode where;Lklist x;
  1990. X{
  1991. XLknode nx = where->next;
  1992. X
  1993. X    if (!l->first) return;
  1994. X    where->next = l->first;
  1995. X    l->last->next = nx;
  1996. X    l->first->last = where;
  1997. X    if (nx) nx->last = l->last;
  1998. X    else x->last = l->last;
  1999. X}
  2000. X
  2001. Xint countnodes(x) /**/
  2002. XLklist x;
  2003. X{
  2004. XLknode y;
  2005. Xint ct = 0;
  2006. X
  2007. X    for (y = firstnode(x); y; incnode(y),ct++);
  2008. X    return ct;
  2009. X}
  2010. X
  2011. SHAR_EOF
  2012. chmod 0644 zsh2.2/src/table.c ||
  2013. echo 'restore of zsh2.2/src/table.c failed'
  2014. Wc_c="`wc -c < 'zsh2.2/src/table.c'`"
  2015. test 6810 -eq "$Wc_c" ||
  2016.     echo 'zsh2.2/src/table.c: original size 6810, current size' "$Wc_c"
  2017. rm -f _shar_wnt_.tmp
  2018. fi
  2019. # ============= zsh2.2/src/text.c ==============
  2020. if test -f 'zsh2.2/src/text.c' -a X"$1" != X"-c"; then
  2021.     echo 'x - skipping zsh2.2/src/text.c (File already exists)'
  2022.     rm -f _shar_wnt_.tmp
  2023. else
  2024. > _shar_wnt_.tmp
  2025. echo 'x - extracting zsh2.2/src/text.c (Text)'
  2026. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.2/src/text.c' &&
  2027. X/*
  2028. X *
  2029. X * text.c - textual representations of syntax trees
  2030. X *
  2031. X * This file is part of zsh, the Z shell.
  2032. X *
  2033. X * This software is Copyright 1992 by Paul Falstad
  2034. X *
  2035. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  2036. X * use this software as long as: there is no monetary profit gained
  2037. X * specifically from the use or reproduction of this software, it is not
  2038. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  2039. X * included prominently in any copy made. 
  2040. X *
  2041. X * The author make no claims as to the fitness or correctness of this software
  2042. X * for any use whatsoever, and it is provided as is. Any use of this software
  2043. X * is at the user's own risk. 
  2044. X *
  2045. X */
  2046. X
  2047. X#include "zsh.h"
  2048. X
  2049. Xstatic char *tptr,*tbuf,*tlim;
  2050. Xstatic int tsiz,tindent,tnewlins;
  2051. X
  2052. X/* add a character to the text buffer */
  2053. X
  2054. Xvoid taddchr(c) /**/
  2055. Xint c;
  2056. X{
  2057. X    *tptr++ = c;
  2058. X    if (tptr == tlim) {
  2059. X        if (!tbuf) { tptr--; return; }
  2060. X        tbuf = realloc(tbuf,tsiz *= 2);
  2061. X        tlim = tbuf+tsiz;
  2062. X        tptr = tbuf+tsiz/2;
  2063. X    }
  2064. X}
  2065. X
  2066. X/* add a string to the text buffer */
  2067. X
  2068. Xvoid taddstr(s) /**/
  2069. Xchar *s;
  2070. X{
  2071. Xint sl = strlen(s);
  2072. X
  2073. X    while (tptr+sl >= tlim) {
  2074. X        int x = tptr-tbuf;
  2075. X
  2076. X        if (!tbuf) return;
  2077. X        tbuf = realloc(tbuf,tsiz *= 2);
  2078. X        tlim = tbuf+tsiz;
  2079. X        tptr = tbuf+x;
  2080. X    }
  2081. X    strcpy(tptr,s);
  2082. X    tptr += sl;
  2083. X}
  2084. X
  2085. X/* add an integer to the text buffer */
  2086. X
  2087. Xvoid taddint(x) /**/
  2088. Xint x;
  2089. X{
  2090. Xchar buf[10];
  2091. X
  2092. X    sprintf(buf,"%d",x);
  2093. X    taddstr(buf);
  2094. X}
  2095. X
  2096. X/* add a newline, or something equivalent, to the text buffer */
  2097. X
  2098. Xvoid taddnl() /**/
  2099. X{
  2100. Xint t0;
  2101. X
  2102. X    if (tnewlins)
  2103. X        {
  2104. X        taddchr('\n');
  2105. X        for (t0 = 0; t0 != tindent; t0++)
  2106. X            taddchr('\t');
  2107. X        }
  2108. X    else
  2109. X        taddstr("; ");
  2110. X}
  2111. X
  2112. X/* get a permanent textual representation of n */
  2113. X
  2114. Xchar *getpermtext(n) /**/
  2115. Xstruct node *n;
  2116. X{
  2117. X    tnewlins = 1;
  2118. X    tbuf = zalloc(tsiz = 32);
  2119. X    tptr = tbuf;
  2120. X    tlim = tbuf+tsiz;
  2121. X    tindent = 1;
  2122. X    gettext2(n);
  2123. X    *tptr = '\0';
  2124. X    untokenize(tbuf);
  2125. X    return tbuf;
  2126. X}
  2127. X
  2128. X/* get a representation of n in a job text buffer */
  2129. X
  2130. Xchar *getjobtext(n) /**/
  2131. Xstruct node *n;
  2132. X{
  2133. Xstatic char jbuf[JOBTEXTSIZE];
  2134. X
  2135. X    tnewlins = 0;
  2136. X    tbuf = NULL;
  2137. X    tptr = jbuf;
  2138. X    tlim = tptr+JOBTEXTSIZE-1;
  2139. X    tindent = 1;
  2140. X    gettext2(n);
  2141. X    *tptr = '\0';
  2142. X    untokenize(jbuf);
  2143. X    return jbuf;
  2144. X}
  2145. X
  2146. X#define gt2(X) gettext2((struct node *) (X))
  2147. X
  2148. X/*
  2149. X    "gettext2" or "type checking and how to avoid it"
  2150. X    an epic function by Paul Falstad
  2151. X*/
  2152. X
  2153. X#define _Cond(X) ((Cond) (X))
  2154. X#define _Cmd(X) ((Cmd) (X))
  2155. X#define _Pline(X) ((Pline) (X))
  2156. X#define _Sublist(X) ((Sublist) (X))
  2157. X#define _List(X) ((List) (X))
  2158. X#define _casecmd(X) ((struct casecmd *) (X))
  2159. X#define _ifcmd(X) ((struct ifcmd *) (X))
  2160. X#define _whilecmd(X) ((struct whilecmd *) (X))
  2161. X
  2162. Xvoid gettext2(n) /**/
  2163. Xstruct node *n;
  2164. X{
  2165. XCmd nn;
  2166. XCond nm;
  2167. X
  2168. X    if (!n)
  2169. X        return;
  2170. X    switch (n->type)
  2171. X        {
  2172. X        case N_LIST:
  2173. X            gt2(_List(n)->left);
  2174. X            if (_List(n)->type == ASYNC)
  2175. X                taddstr(" &");
  2176. X            simplifyright(_List(n));
  2177. X            if (_List(n)->right)
  2178. X                {
  2179. X                if (tnewlins)
  2180. X                    taddnl();
  2181. X                else
  2182. X                    taddstr((_List(n)->type == ASYNC) ? " " : "; ");
  2183. X                gt2(_List(n)->right);
  2184. X                }
  2185. X            break;
  2186. X        case N_SUBLIST:
  2187. X            if (_Sublist(n)->flags & PFLAG_NOT)
  2188. X                taddstr("! ");
  2189. X            if (_Sublist(n)->flags & PFLAG_COPROC)
  2190. X                taddstr("coproc ");
  2191. X            gt2(_Sublist(n)->left);
  2192. X            if (_Sublist(n)->right)
  2193. X                {
  2194. X                taddstr((_Sublist(n)->type == ORNEXT) ? " || " : " && ");
  2195. X                gt2(_Sublist(n)->right);
  2196. X                }
  2197. X            break;
  2198. X        case N_PLINE:
  2199. X            gt2(_Pline(n)->left);
  2200. X            if (_Pline(n)->type == PIPE)
  2201. X                {
  2202. X                taddstr(" | ");
  2203. X                gt2(_Pline(n)->right);
  2204. X                }
  2205. X            break;
  2206. X        case N_CMD:
  2207. X            nn = _Cmd(n);
  2208. X            if (nn->flags & CFLAG_EXEC)
  2209. X                taddstr("exec ");
  2210. X            if (nn->flags & CFLAG_COMMAND)
  2211. X                taddstr("command ");
  2212. X            switch (nn->type)
  2213. X                {
  2214. X                case SIMPLE:
  2215. X                    getsimptext(nn);
  2216. X                    break;
  2217. X                case SUBSH:
  2218. X                    taddstr("( ");
  2219. X                    tindent++;
  2220. X                    gt2(nn->u.list);
  2221. X                    tindent--;
  2222. X                    taddstr(" )");
  2223. X                    break;
  2224. X                case ZCTIME:
  2225. X                    taddstr("time ");
  2226. X                    tindent++;
  2227. X                    gt2(nn->u.pline);
  2228. X                    tindent--;
  2229. X                    break;
  2230. X                case FUNCDEF:
  2231. X                    taddlist(nn->args);
  2232. X                    taddstr(" () {");
  2233. X                    tindent++;
  2234. X                    taddnl();
  2235. X                    gt2(nn->u.list);
  2236. X                    tindent--;
  2237. X                    taddnl();
  2238. X                    taddstr("}");
  2239. X                    break;
  2240. X                case CURSH:
  2241. X                    taddstr("{ ");
  2242. X                    tindent++;
  2243. X                    gt2(nn->u.list);
  2244. X                    tindent--;
  2245. X                    taddstr(" }");
  2246. X                    break;
  2247. X                case CFOR:
  2248. X                case CSELECT:
  2249. X                    taddstr((nn->type == CFOR) ? "for " : "select ");
  2250. X                    taddstr(nn->u.forcmd->name);
  2251. X                    if (nn->u.forcmd->inflag)
  2252. X                        {
  2253. X                        taddstr(" in ");
  2254. X                        taddlist(nn->args);
  2255. X                        }
  2256. X                    taddnl();
  2257. X                    taddstr("do");
  2258. X                    tindent++;
  2259. X                    taddnl();
  2260. X                    gt2(nn->u.forcmd->list);
  2261. X                    taddnl();
  2262. X                    tindent--;
  2263. X                    taddstr("done");
  2264. X                    break;
  2265. X                case CIF:
  2266. X                    gt2(nn->u.ifcmd);
  2267. X                    taddstr("fi");
  2268. X                    break;
  2269. X                case CCASE:
  2270. X                    taddstr("case ");
  2271. X                    taddlist(nn->args);
  2272. X                    taddstr(" in");
  2273. X                    tindent++;
  2274. X                    taddnl();
  2275. X                    gt2(nn->u.casecmd);
  2276. X                    tindent--;
  2277. X                    if (tnewlins)
  2278. X                        taddnl();
  2279. X                    else
  2280. X                        taddchr(' ');
  2281. X                    taddstr("esac");
  2282. X                    break;
  2283. X                case COND:
  2284. X                    taddstr("[[ ");
  2285. X                    gt2(nn->u.cond);
  2286. X                    taddstr(" ]]");
  2287. X                    break;
  2288. X                case CREPEAT:
  2289. X                    taddstr("repeat ");
  2290. X                    taddlist(nn->args);
  2291. X                    taddnl();
  2292. X                    taddstr("do");
  2293. X                    tindent++;
  2294. X                    taddnl();
  2295. X                    gt2(nn->u.list);
  2296. X                    tindent--;
  2297. X                    taddnl();
  2298. X                    taddstr("done");
  2299. X                    break;
  2300. X                case CWHILE:
  2301. X                    gt2(nn->u.whilecmd);
  2302. X                    break;
  2303. X                }
  2304. X            getredirs(nn);
  2305. X            break;
  2306. X        case N_COND:
  2307. X            nm = _Cond(n);
  2308. X            switch (nm->type)
  2309. X                {
  2310. X                case COND_NOT:
  2311. X                    taddstr("! ");
  2312. X                    gt2(nm->left);
  2313. X                    break;
  2314. X                case COND_AND:
  2315. X                    taddstr("( ");
  2316. X                    gt2(nm->left);
  2317. X                    taddstr(" && ");
  2318. X                    gt2(nm->right);
  2319. X                    taddstr(" )");
  2320. X                    break;
  2321. X                case COND_OR:
  2322. X                    taddstr("( ");
  2323. X                    gt2(nm->left);
  2324. X                    taddstr(" || ");
  2325. X                    gt2(nm->right);
  2326. X                    taddstr(" )");
  2327. X                    break;
  2328. X                default:
  2329. X                    {
  2330. X                    static char *c1[] = {
  2331. X                        " = "," != "," < "," > "," -nt "," -ot "," -ef "," -eq ",
  2332. X                        " -ne "," -lt "," -gt "," -le "," -ge "
  2333. X                        };
  2334. X                    if (nm->right)
  2335. X                        taddstr(nm->left);
  2336. X                    if (nm->type <= COND_GE)
  2337. X                        taddstr(c1[nm->type-COND_STREQ]);
  2338. X                    else
  2339. X                        {
  2340. X                        char c2[5];
  2341. X                        c2[0] = ' '; c2[1] = '-';
  2342. X                        c2[2] = nm->type;
  2343. X                        c2[3] = ' '; c2[4] = '\0';
  2344. X                        taddstr(c2);
  2345. X                        }
  2346. X                    taddstr((nm->right) ? nm->right : nm->left);
  2347. X                    }
  2348. X                    break;
  2349. X                }
  2350. X            break;
  2351. X        case N_CASE:
  2352. X            taddstr(_casecmd(n)->pat);
  2353. X            taddstr(") ");
  2354. X            tindent++;
  2355. X            gt2(_casecmd(n)->list);
  2356. X            tindent--;
  2357. X            taddstr(";;");
  2358. X            if (tnewlins)
  2359. X                taddnl();
  2360. X            else
  2361. X                taddchr(' ');
  2362. X            gt2(_casecmd(n)->next);
  2363. X            break;
  2364. X        case N_IF:
  2365. X            if (_ifcmd(n)->ifl)
  2366. X                {
  2367. X                taddstr("if ");
  2368. X                tindent++;
  2369. X                gt2(_ifcmd(n)->ifl);
  2370. X                tindent--;
  2371. X                taddnl();
  2372. X                taddstr("then");
  2373. X                }
  2374. X            else
  2375. X                taddchr('e');
  2376. X            tindent++;
  2377. X            taddnl();
  2378. X            gt2(_ifcmd(n)->thenl);
  2379. X            tindent--;
  2380. X            taddnl();
  2381. X            if (_ifcmd(n)->next)
  2382. X                {
  2383. X                taddstr("els");
  2384. X                gt2(_ifcmd(n)->next);
  2385. X                }
  2386. X            break;
  2387. X        case N_WHILE:
  2388. X            taddstr((_whilecmd(n)->cond) ? "until " : "while ");
  2389. X            tindent++;
  2390. X            gt2(_whilecmd(n)->cont);
  2391. X            tindent--;
  2392. X            taddnl();
  2393. X            taddstr("do");
  2394. X            tindent++;
  2395. X            taddnl();
  2396. X            gt2(_whilecmd(n)->loop);
  2397. X            tindent--;
  2398. X            taddnl();
  2399. X            taddstr("done");
  2400. X            break;
  2401. X        }
  2402. X}
  2403. X
  2404. Xvoid getsimptext(cmd) /**/
  2405. XCmd cmd;
  2406. X{
  2407. XLknode n;
  2408. X
  2409. X    for (n = firstnode(cmd->vars); n; incnode(n))
  2410. X        {
  2411. X        struct varasg *v = getdata(n);
  2412. X
  2413. X        taddstr(v->name);
  2414. X        taddchr('=');
  2415. X        if ((v->type & PMTYPE) == PMFLAG_A)
  2416. X            {
  2417. X            taddchr('(');
  2418. X            taddlist(v->arr);
  2419. X            taddstr(") ");
  2420. X            }
  2421. X        else
  2422. X            {
  2423. X            taddstr(v->str);
  2424. X            taddchr(' ');
  2425. X            }
  2426. X        }
  2427. X    taddlist(cmd->args);
  2428. X}
  2429. X
  2430. Xvoid getredirs(cmd) /**/
  2431. XCmd cmd;
  2432. X{
  2433. XLknode n;
  2434. Xstatic char *fstr[] = {
  2435. X    ">",">!",">>",">>!",">&",">&!",">>&",">>&!","<","<<",
  2436. X    "<<-","<<<","<&",">&-","..",".."
  2437. X    };
  2438. X
  2439. X    taddchr(' ');
  2440. X    for (n = firstnode(cmd->redir); n; incnode(n))
  2441. X        {
  2442. X        struct redir *f = getdata(n);
  2443. X
  2444. X        switch(f->type)
  2445. X            {
  2446. X            case WRITE: case WRITENOW: case APP: case APPNOW: case READ:
  2447. X            case HERESTR:
  2448. X                if (f->fd1 != ((f->type == READ) ? 0 : 1))
  2449. X                    taddchr('0'+f->fd1);
  2450. X                taddstr(fstr[f->type]);
  2451. X                taddchr(' ');
  2452. X                taddstr(f->name);
  2453. X                taddchr(' ');
  2454. X                break;
  2455. X            case MERGE: case MERGEOUT:
  2456. X                if (f->fd1 != ((f->type == MERGEOUT) ? 1 : 0))
  2457. X                    taddchr('0'+f->fd1);
  2458. X                taddstr(fstr[f->type]);
  2459. X                taddchr(' ');
  2460. X                taddint(f->fd2);
  2461. X                taddchr(' ');
  2462. X                break;
  2463. X            case CLOSE:
  2464. X                taddchr(f->fd1+'0');
  2465. X                taddstr(">&- ");
  2466. X                break;
  2467. X            case INPIPE:
  2468. X            case OUTPIPE:
  2469. X                if (f->fd1 != ((f->type == INPIPE) ? 0 : 1))
  2470. X                    taddchr('0'+f->fd1);
  2471. X                taddstr((f->type == INPIPE) ? "< " : "> ");
  2472. X                taddstr(f->name);
  2473. X                taddchr(' ');
  2474. X                break;
  2475. X            }
  2476. X        }
  2477. X    tptr--;
  2478. X}
  2479. X
  2480. Xvoid taddlist(l) /**/
  2481. XLklist l;
  2482. X{
  2483. XLknode n;
  2484. X
  2485. X    for (n = firstnode(l); n; incnode(n))
  2486. X        {
  2487. X        taddstr(getdata(n));
  2488. X        taddchr(' ');
  2489. X        }
  2490. X    tptr--;
  2491. X}
  2492. SHAR_EOF
  2493. chmod 0644 zsh2.2/src/text.c ||
  2494. echo 'restore of zsh2.2/src/text.c failed'
  2495. Wc_c="`wc -c < 'zsh2.2/src/text.c'`"
  2496. test 8584 -eq "$Wc_c" ||
  2497.     echo 'zsh2.2/src/text.c: original size 8584, current size' "$Wc_c"
  2498. rm -f _shar_wnt_.tmp
  2499. fi
  2500. # ============= zsh2.2/src/utils.c ==============
  2501. if test -f 'zsh2.2/src/utils.c' -a X"$1" != X"-c"; then
  2502.     echo 'x - skipping zsh2.2/src/utils.c (File already exists)'
  2503.     rm -f _shar_wnt_.tmp
  2504. else
  2505. > _shar_wnt_.tmp
  2506. echo 'x - extracting zsh2.2/src/utils.c (Text)'
  2507. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.2/src/utils.c' &&
  2508. X/*
  2509. X *
  2510. X * utils.c - miscellaneous utilities
  2511. X *
  2512. X * This file is part of zsh, the Z shell.
  2513. X *
  2514. X * This software is Copyright 1992 by Paul Falstad
  2515. X *
  2516. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  2517. X * use this software as long as: there is no monetary profit gained
  2518. X * specifically from the use or reproduction of this software, it is not
  2519. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  2520. X * included prominently in any copy made. 
  2521. X *
  2522. X * The author make no claims as to the fitness or correctness of this software
  2523. X * for any use whatsoever, and it is provided as is. Any use of this software
  2524. X * is at the user's own risk. 
  2525. X *
  2526. X */
  2527. X
  2528. X#include "zsh.h"
  2529. X#include <pwd.h>
  2530. X#include <errno.h>
  2531. X#ifdef __hpux
  2532. X#include <ndir.h>
  2533. X#else
  2534. X#ifndef SYSV
  2535. X#include <sys/dir.h>
  2536. X#endif
  2537. X#endif
  2538. X#include <fcntl.h>
  2539. X
  2540. X#ifdef SYSV
  2541. X#define direct dirent
  2542. X#undef TIOCGWINSZ
  2543. Xint readlink(s,t,z)
  2544. Xchar *s;char *t;int z;
  2545. X{
  2546. Xreturn -1;
  2547. X}
  2548. X#endif
  2549. X
  2550. X/* source a file */
  2551. X
  2552. Xint source(s) /**/
  2553. Xchar *s;
  2554. X{
  2555. Xint fd,cj = thisjob;
  2556. Xint oldlineno = lineno,oldshst;
  2557. XFILE *obshin = bshin;
  2558. X
  2559. X    fd = SHIN;
  2560. SHAR_EOF
  2561. true || echo 'restore of zsh2.2/src/utils.c failed'
  2562. fi
  2563. echo 'End of zsh2.2 part 11'
  2564. echo 'File zsh2.2/src/utils.c is continued in part 12'
  2565. echo 12 > _shar_seq_.tmp
  2566. exit 0
  2567.  
  2568. exit 0 # Just in case...
  2569.